﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MvcToolbox
{
    /// <summary>
    /// Class GridColumnFactory
    /// </summary>
    /// <typeparam name="TModel">The type of the T model.</typeparam>
    /// <typeparam name="TValue">The type of the T value.</typeparam>
    public class GridColumnFactory<TModel, TValue>
    {
        /// <summary>
        /// The MVC grid
        /// </summary>
        private IMvcGrid<TModel, TValue> mvcGrid;

        /// <summary>
        /// Initializes a new instance of the <see cref="GridColumnFactory{TModel, TValue}"/> class.
        /// </summary>
        /// <param name="mvcGrid">The MVC grid.</param>
        public GridColumnFactory(IMvcGrid<TModel, TValue> mvcGrid)
        {
            // TODO: Complete member initialization
            this.mvcGrid = mvcGrid;
        }

        /// <summary>
        /// Gets or sets the column.
        /// </summary>
        /// <value>The column.</value>
        public GridColumn<TModel, TValue> Column { get; set; }

        /// <summary>
        /// Bounds the specified expression.
        /// </summary>
        /// <typeparam name="T">Type of value</typeparam>
        /// <param name="expression">The expression.</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> Bound<T>(System.Linq.Expressions.Expression<System.Func<TValue, T>> expression)
        {
            GridBoundColumn<TModel, TValue, T> item = new GridBoundColumn<TModel, TValue, T>(this.mvcGrid, expression);
            this.Column = item;
            this.mvcGrid.ColumnsDefinition.Add(item);
            return this;
        }

        /// <summary>
        /// Bounds the specified expression.
        /// </summary>
        /// <typeparam name="T">Type of value</typeparam>
        /// <param name="expression">The expression.</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> UnBound()
        {
            GridColumn<TModel, TValue> item = new GridColumn<TModel, TValue>();
            this.Column = item;
            this.mvcGrid.ColumnsDefinition.Add(item);
            return this;
        }

        /// <summary>
        /// Hide the specified column.
        /// </summary>
        /// <param name="hidden">if set to <c>true</c> [hidden].</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> Hidden(bool hidden = true)
        {
            this.Column.IsHide = hidden;
            return this as GridColumnFactory<TModel, TValue>;
        }

        /// <summary>
        /// Noes the order.
        /// </summary>
        /// <returns>GridColumnFactory{`0`1}.</returns>
        public GridColumnFactory<TModel, TValue> NoOrder()
        {
            this.Column.NoOrder = true;
            return this as GridColumnFactory<TModel, TValue>;
        }

        /// <summary>
        /// Templates the specified template.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> Template(string template)
        {
            this.Column.Template = template;
            return this as GridColumnFactory<TModel, TValue>;
        }

        /// <summary>
        /// Specify width.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> Width(int width)
        {
            this.Column.Width = width;
            return this as GridColumnFactory<TModel, TValue>;
        }

        /// <summary>
        /// Formats the specified format.
        /// </summary>
        /// <param name="format">The format.</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> Format(string format)
        {
            this.Column.Format = format;
            return this as GridColumnFactory<TModel, TValue>;
        }
        /// <summary>
        /// Bounds the specified expression.
        /// </summary>
        /// <typeparam name="T">Type of value</typeparam>
        /// <param name="expression">The expression.</param>
        /// <returns>The GridColumnFactory.</returns>
        public GridColumnFactory<TModel, TValue> Format<T>(string format, System.Linq.Expressions.Expression<System.Func<TValue, T>> expression)
        {
            this.Column.Format = format;
            dynamic col = this.Column;
            col.FormatExpression = expression;
            return this as GridColumnFactory<TModel, TValue>;
        }
    }
}
